#!/usr/bin/env python3.6
# -*- encoding: utf-8 -*-
'''
@File    :   views.py
@Time    :   2020/04/12 15:45:34
@Author  :   Tang Jing 
@Version :   1.0.0
@Contact :   yeihizhi@163.com
@License :   (C)Copyright 2020
@Desc    :   None
'''

# here put the import lib
import json
import re
import six
# django import lib
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from rest_framework import viewsets, routers
from rest_framework.views import APIView
from rest_framework.schemas import AutoSchema
from rest_framework import status
from rest_framework.renderers import JSONRenderer
from rest_framework.decorators import *
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django.db.models.expressions import RawSQL
from api.models import category
from src.settings import REST_FRAMEWORK, SPIDER_Notify
from general.remote import REMOTE_CALL

# project import lib
from api.restframework.serializersModels import *
from api.models import *
from TDhelper.network.http.http_helper import m_http
from TDhelper.network.http.m3u8 import m3u8, M3U8_STATUS, cfg
from general.db import select
from api.logic.spiderrecv import saveChildType, saveMsg, saveTopType

# code start
m3u8_Cfg = {"cfg": {
    'timeout': 5,
    'reconnect': 3
},
    "ismerge": False,  # 是否合并ts文件
    "save-folder": "tmp",  # 临时文件件
    "download-poolsize": 20,  # 下载结程
    "buffer-index": 5  # 下载多少文件后生成索引文件
}

m3u8Thread = m3u8(m3u8Cfg= m3u8_Cfg)


class moviesView(APIView):

    @schema(None)
    def get(self, request, format=None):
        page = 1
        if 'page' in request.query_params:
            page = int(request.query_params['page'])
        count = 0
        where_str = ''
        if 'category_id' in request.query_params:
            sql = "select id from category where id={0} or parent_id={1}".format(
                request.query_params['category_id'], request.query_params['category_id'])
            category_ret = select(sql)
            if category_ret:
                where_str = " and category_id in("
                for item in category_ret:
                    where_str += str(item[0])+','
                where_str += ') '
                where_str = where_str.replace(',)', ')')
        if 'name' in request.query_params:
            where_str = " and name like '%{0}%' ".format(
                request.query_params['name'])
        sql = "select count(id) from movie_list where enable=1{0}".format(
            where_str)
        ret = select(sql)
        if ret:
            count = ret[0][0]
        totalPage = int(count/REST_FRAMEWORK['PAGE_SIZE'])
        if count % REST_FRAMEWORK['PAGE_SIZE'] > 0:
            totalPage += 1
        if page > totalPage:
            page = totalPage
        if page < 1:
            page = 1
        sql = "select *from movie_list where enable=1{2} order by movie_list.last_update_time desc limit {0},{1}".format(
            (page-1)*REST_FRAMEWORK['PAGE_SIZE'], REST_FRAMEWORK['PAGE_SIZE'], where_str)
        ret = select(sql)
        movies = []
        if ret:
            for item in ret:
                movies.append({
                    "id": item[0],
                    "name": item[1],
                    "remark": item[2],
                    "director": item[3],
                    "performer": item[4],
                    "number": item[5],
                    "category": item[6],
                    "country": item[7],
                    "language": item[8],
                    "year": item[9],
                    "last_update_time": item[10],
                    "tag": item[11],
                    "description": item[12],
                    "cover": item[13],
                    "alias": item[14],
                })
        data = {"count": count, "next": None,
                "previous": None, "results": movies}
        request_path = request._request._current_scheme_host+request._request.path
        if page+1 <= totalPage:
            m_count = 0
            next_path = request_path
            if 'page' in request.query_params:
                for item in request.query_params:
                    if m_count == 0:
                        next_path += "?"
                    else:
                        next_path += "&"
                    m_count += 1
                    if item == 'page':
                        next_path += 'page=' + str(page+1)
                    else:
                        next_path += item+'='+request.query_params[item]
            else:
                if len(request.query_params) <= 0:
                    next_path += '?page=' + str(page+1)
                else:
                    next_path += '&page=' + str(page+1)
            data['next'] = next_path
        if page-1 > 0:
            m_count = 0
            previous_path = request_path
            for item in request.query_params:
                if m_count == 0:
                    previous_path += "?"
                else:
                    previous_path += "&"
                m_count += 1
                if item == 'page':
                    previous_path += 'page=' + str(page-1)
                else:
                    previous_path += item+'='+request.query_params[item]
            data['previous'] = previous_path
        return Response(data)


class moviesViewSet(viewsets.ViewSet):
    queryset = movie_list.objects.select_related('category').filter(
        enable__exact=True).order_by("-last_update_time")
    serializer_class = movieSerializer
    pagination_class = PageNumberPagination
    # schema= CustomSchema() #set schema swagger

    def list(self, request):
        m_queryset = self.queryset
        m_categoryId = None
        m_name = None
        if "category_id" in request.query_params:
            m_categoryId = request.query_params.get('category_id')
            if m_categoryId:
                ret = category.objects.filter(id=m_categoryId)
                if ret:
                    ret_backup = ret
                    if ret[0].parent_id == 0:
                        ret = category.objects.filter(parent_id=ret[0].id)
                        if not ret:
                            ret = [ret_backup[0].id]
                m_queryset = m_queryset.filter(category_id__in=ret)
        if "name" in request.query_params:
            m_name = request.query_params.get('name')
            if m_name:
                m_queryset = m_queryset.filter(name__icontains=m_name)
        pg = PageNumberPagination()
        m_page_result = pg.paginate_queryset(
            queryset=m_queryset, request=request, view=self)
        #m_serializer= movieSerializer(m_queryset, many=True, context={'request':request})
        m_serializer = movieSerializer(
            instance=m_page_result, many=True, context={'request': request})
        m_data = pg.get_paginated_response(m_serializer.data)
        return Response(data=m_data.data)

    def create(self, request):
        pass

    def retrieve(self, request, pk=None):
        m_queryset = movie_list.objects.filter(pk=pk)
        m_instance = get_object_or_404(m_queryset, pk=pk)
        m_serializer = movieSerializer(
            instance=m_instance, context=serializer_context)
        return Response(data=m_serializer.data)

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass


class categorysViewSet(viewsets.ViewSet):
    queryset = category.objects.filter(
        enable__exact=True).order_by('parent_id', 'id')
    serializer_class = categorySerializer
    # permission_classes = [IsAuthenticated]
    # schema= CustomSchema() #set schema swagger

    def list(self, request):
        queryset = self.queryset
        m_serializer = categorySerializer(
            instance=queryset, many=True, context=serializer_context)
        return Response(m_serializer.data)

    def retrieve(self, request, pk=None):
        m_instance = get_object_or_404(self.queryset, pk=pk)
        m_serializer = categorySerializer(
            instance=m_instance, context=serializer_context)
        return Response(m_serializer.data)

    @action(detail=True, methods=['PUT'])
    def enable(self, request, pk=None):
        ret = False
        m_serializer = categorySerializer(data=request.data)
        if m_serializer.is_valid():
            ret = m_serializer.enable(pk, m_serializer.validated_data)
        return Response({'state': ret})


class playUrlViewSet(viewsets.ViewSet):
    queryset = movie_play_list.objects.all()
    serializer_class = playUrlSerializer
    # permission_classes = [IsAuthenticated]
    # schema= CustomSchema() #set schema swagger
    # pagination_class = PageNumberPagination

    def list(self, request):
        m_movie_id = request.query_params.get('movie_id')
        if m_movie_id:
            m_queryset = self.queryset.filter(
                movie_id__exact=m_movie_id).order_by('spider_sources_index', 'sources', 'id')
            m_serializer = playUrlSerializer(
                instance=m_queryset, many=True, context={'request': request})
            return Response(m_serializer.data)
        else:
            return Response(data={}, status=status.HTTP_400_BAD_REQUEST)

    def create(self, request):
        pass

    def retrieve(self, request, pk=None):
        pass

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass


class m3u8(APIView):

    def get(self, request):
        m3u8_playurl = request.query_params.get('p_url')
        response_html, response_status = m_http().getcontent(m3u8_playurl)
        ret = {
            "m3u8": ''
        }
        if response_status == 200:
            result = re.search(
                '(http|https|/).*?\.(m3u8|mp4|avi|mov|mpg|mpeg)', response_html, re.M | re.I)
            if result:
                ret['m3u8'] = result.group()
                result = None
                result = re.match('^(http(s)?:\/\/.*?\/)',
                                  ret['m3u8'], re.M | re.I)
                if not result:
                    result = re.match('^(http(s)?:\/\/.*?\/)',
                                      m3u8_playurl, re.M | re.I)
                    if result:
                        base_url = result.group()
                        ret['m3u8'] = base_url + ret['m3u8']
        return Response(ret)

class spiderByName(APIView):
    def get(self, request):
        if 'key' in request.query_params:
            fd_key= request.query_params.get('key')
            if fd_key:
                # todo nodify spider.
                api_url= SPIDER_Notify.format(fd_key)
                body, status= REMOTE_CALL.getcontent(api_url, p_timeout= 10)
                if status == 200:
                    body= body.replace("'","\"")
                    ret=json.loads(body, encoding='utf-8')
                    return Response(ret)
                else:
                    return Response({'state': False, 'msg': body})
            else:
                return Response({'state':False, 'msg':'key is none.'})
        else:
            return Response({'state':False, 'msg':'query params key can not found.'})

class proxy(APIView):
    def get(self, request):
        m3u8_playurl = request.query_params.get('uri')
        response,state= m3u8Thread.Get(m3u8_playurl)
        m_file=m3u8Thread.GetM3U8File()
        if m_file:
            return Response(m_file)
        return Response('')

class spiderSaveTopType(APIView):
    def post(self, request):
        data= request.data['data']
        try:
            saveTopType(data)
            return Response({"state":True,"data":data})
        except Exception as e:
            return Response({"state":False,"data":data,"msg":""+e+""})

class spiderSaveChildType(APIView):
    def post(self,request):
        data= request.data['data']
        try:
            saveChildType(data)
            return Response({"state":True,"data":data})
        except Exception as e:
            return Response({"state":False,"data":data,"msg":""+e+""})

class spiderSaveMsg(APIView):
    def post(self,request):
        data= request.data['data']
        try:
            saveMsg(data)
            return Response({"state":True,"data":data})
        except Exception as e:
            return Response({"state":False,"data":data,"msg":""+e+""})